package com.sgchen.security.util;

import org.reflections.Reflections;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class ReflectionsLogToggler {
    private static Field logField;
    private static Object originalLog;
    private static boolean isLogDisabled = false;
    private static boolean isInitialized = false;

    /**
     * 初始化反射访问器
     */
    private static synchronized void initialize() {
        if (!isInitialized) {
            try {
                logField = Reflections.class.getDeclaredField("log");
                logField.setAccessible(true);

                // 移除final修饰符
                Field modifiersField = Field.class.getDeclaredField("modifiers");
                modifiersField.setAccessible(true);
                modifiersField.setInt(logField, logField.getModifiers() & ~Modifier.FINAL);

                isInitialized = true;
            } catch (Exception e) {
                throw new RuntimeException("无法初始化Reflections日志访问器", e);
            }
        }
    }

    /**
     * 禁用Reflections日志
     */
    public static void disableLogging() {
        try {
            if (!isInitialized) initialize();
            if (!isLogDisabled) {
                originalLog = logField.get(null);
                logField.set(null, null);
                isLogDisabled = true;
            }
        } catch (Exception e) {
            throw new RuntimeException("无法禁用Reflections日志", e);
        }
    }

    /**
     * 恢复Reflections日志
     */
    public static void restoreLogging() {
        try {
            if (!isInitialized) return;
            if (isLogDisabled) {
                logField.set(null, originalLog);
                isLogDisabled = false;
            }
        } catch (Exception e) {
            throw new RuntimeException("无法恢复Reflections日志", e);
        }
    }

    /**
     * 在无日志模式下执行Reflections操作
     */
    public static <T> T executeSilently(ReflectionsOperation<T> operation) {
        disableLogging();
        try {
            return operation.execute();
        } finally {
            restoreLogging();
        }
    }

    @FunctionalInterface
    public interface ReflectionsOperation<T> {
        T execute();
    }
}